// ==UserScript== // @name twitter 关注脚本 // @namespace twitter.user.js // @version 0.1.0 // @description twitter 自动关注/取关用户列表 // @author Homie_Xu // @match https://twitter.com/* // run-at document-idle // ==/UserScript== /* ==UserConfig== group1: configX: title: 运行配置 description: 这是一个文本类型的配置 default: 默认值 ==/UserConfig== */ (function () { 'use strict'; class Layout { container = null btnStatus = {} constructor(title) { this.generateContainer(title) } appendTo(nodeOrCommonType, node) { if (nodeOrCommonType === 'body') nodeOrCommonType = document.body nodeOrCommonType.appendChild(node) } generateNode(nodeType, css, text, id, className) { let node = document.createElement(nodeType) // 赋予属性 text && (node.innerHTML = text) id && (node.id = id) className && (node.className = className) // 赋予样式 btnStyle = node.style Object.keys(css || {}).forEach(key => btnStyle[key] = css[key]) return node } generateContainer(title) { // 初始化容器 const wrapperBoxCss = { position: 'fixed', top: '1%', left: '1%', fontSize: '12px', fontWeight: 'bold' } const wrapperBox = this.generateNode('div', wrapperBoxCss, null, null, 'css-wrapperBox') this.appendTo('body', wrapperBox) // 有标题生成标题 if (title) { const boxTitleCss = { paddingBottom: '4px', borderBottom: '1px solid #ccc' } const boxTitle = this.generateNode('div', boxTitleCss, title) this.appendTo(wrapperBox, boxTitle) } // 生成列表 const ulListCss = { paddingBottom: '4px', listStyle: 'none', padding: 0 } const ulList = this.generateNode('ul', ulListCss) this.appendTo(wrapperBox, ulList) this.container = ulList } genrateItem(id, descText) { // status: true | false const descCss = { color: 'rgba(0,0,0,.5)', fontSize: '10px' } const p = this.generateNode('p', descCss, descText) const buttonCss = { // color: status ? '#fff' : 'rgb(244,33,46)', // backgroundColor: status ? 'rgb(29, 155, 240)' : 'pink', color: '#fff', backgroundColor: 'rgb(29, 155, 240)', borderRadius: '12px', boxShadow: 'rgb(0 0 0 / 8%) 0px 8px 28px', cursor: 'pointer', fontSize: '10px' } const button = this.generateNode('button', buttonCss, '开始运行', id) const liItem = this.generateNode('li') this.appendTo(liItem, p) this.appendTo(liItem, button) this.appendTo(this.container, liItem) this.btnStatus[id] = false return { buttonId: id, button } } toggleButton(buttonId) { // TODO 增加中间状态 const button = document.getElementById(buttonId) this.btnStatus[buttonId] = !this.btnStatus[buttonId] button.innerHTML = this.btnStatus[buttonId] ? '停止运行' : '开始运行' button.style.color = this.btnStatus[buttonId] ? 'rgb(244,33,46)' : '#fff' button.style.backgroundColor = this.btnStatus[buttonId] ? 'pink' : 'rgb(29, 155, 240)' return { id: buttonId, node: button, action: this.btnStatus[buttonId] ? 'ON' : 'OFF', status: this.btnStatus[buttonId] } } } const listener = (target) => { } window.addEventListener('load', () => { // addButton('Autofollow', selectReadFn, 'button.autofollow') const layout = new Layout('Twitter 自动关注脚本 - By @Homie_Xu') const { buttonId: buttonIdAutoFollow, button: buttonAutoFollow } = layout.genrateItem( '#one', '1. 自动关注当前列表中的用户' ) let followTimer = null let unFollowTimer = null buttonAutoFollow.onclick = () => { const { status } = layout.toggleButton(buttonIdAutoFollow) if (status) { console.log('开始:自动关注当前列表中的用户') let btns = document.querySelectorAll("[data-testid]") let followBtns = Array.from(btns).filter(btn => { return btn.getAttribute('data-testid').includes('-follow') }) let currentIndex = 0 if (currentIndex >= followBtns.length) { layout.toggleButton(buttonIdAutoFollow) clearInterval(timer) return console.log(`结束:自动关注当前列表中的用户`) } followTimer = setInterval(() => { console.log(`当前关注:${currentIndex + 1}`) followBtns[currentIndex].click() currentIndex++ }, 3000) } else { console.log(`结束:自动关注当前列表中的用户`) clearInterval(followTimer) } } const { buttonId: buttonIdCancelFollow, button: buttonCancelFollow } = layout.genrateItem( '#two', '2. 自动取消关注当前列表中的用户' ) buttonCancelFollow.onclick = () => { const { status } = layout.toggleButton(buttonIdCancelFollow) if (status) { console.log('开始:自动取消关注当前列表中的用户') let btns = document.querySelectorAll("[data-testid]") let unfollowBtns = Array.from(btns).filter(btn => { return btn.getAttribute('data-testid').includes('-unfollow') }) let currentIndex = 0 if (currentIndex >= unfollowBtns.length) { layout.toggleButton(buttonIdCancelFollow) clearInterval(timer) return console.log('结束:自动取消关注当前列表中的用户') } unFollowTimer = setInterval(() => { unfollowBtns[currentIndex].click() console.log(`当前取消关注:${currentIndex + 1}`) setTimeout(() => { document.querySelector("[data-testid='confirmationSheetConfirm']").click() }, 500); currentIndex++ }, 3500) } else { console.log('结束:自动取消关注当前列表中的用户') clearInterval(unFollowTimer) } } }) })();